package info.cs52.fes.action.stats;

import info.cs52.fes.FesAction;
import info.cs52.fes.dao.RecipeDAO;
import info.cs52.fes.data.Recipe;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RecipeStats extends FesAction {
	
	private static final String RULE_PATH = "/prolog/recipes.pl";
	private static final Pattern RECIPE_PATTERN = Pattern.compile("recipe\\((.+)\\)");
	private static final Pattern AV_PATTERN = Pattern.compile("fact\\(av\\((.+)\\((.+)\\), .+\\), .+\\).");
	private LinkedList<String> warnings;
	private SortedMap<String, SortedMap<String, String>> recipeMap;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				RecipeStats.class.getResourceAsStream(RULE_PATH)));
		warnings = new LinkedList<String>();
		recipeMap = new TreeMap<String, SortedMap<String, String>>();
		TreeSet<String> attribs = new TreeSet<String>();
		String line;
		while ((line = reader.readLine()) != null) {
			line = line.trim();
			Matcher recipeMatcher = RECIPE_PATTERN.matcher(line);
			if (recipeMatcher.find()) {
				recipeMap.put(recipeMatcher.group(1), new TreeMap<String, String>());
				continue;
			}
			
			Matcher avMatcher = AV_PATTERN.matcher(line);
			if (avMatcher.find()) {
				String attrib = avMatcher.group(1);
				String recipe = avMatcher.group(2);
				if (!recipeMap.containsKey(recipe)) {
					warnings.add("Recipe not defined before its attribute: " + recipe);
				}
				if (recipeMap.get(recipe).containsKey(attrib)) {
					warnings.add("Duplicate attribute: " + attrib + "(" + recipe + ")");
				}
				recipeMap.get(recipe).put(attrib, line);
				attribs.add(attrib);
			}
		}
		// find missing attributes
//		for (Map.Entry<String, SortedMap<String, String>> recipeEntry : recipeMap.entrySet()) {
//			String recipe = recipeEntry.getKey();
//			for (String attrib : attribs) {
//				if (!recipeEntry.getValue().containsKey(attrib)) {
//					warnings.add("Missing attribute: " + attrib + "(" + recipe + ")");
//				}
//			}
//		}
		// find missing database entries
		for (Map.Entry<String, SortedMap<String, String>> recipeEntry : recipeMap.entrySet()) {
			Recipe recipe = RecipeDAO.findByName(recipeEntry.getKey());
			if (recipe == null) {
				warnings.add("Not found in database: " + recipeEntry.getKey());
			}
		}
		reader.close();
	}
	
	public LinkedList<String> getWarnings() {
		return warnings;
	}
	
	public SortedMap<String, SortedMap<String, String>> getRecipeMap() {
		return recipeMap;
	}
	
}
